package com.compare;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.setting.dialect.Props;
import com.compare.config.MyBatisPlusConfig;
import com.compare.mapper.ObsCompareMapper;
import com.compare.pojo.ObsCompare;
import com.compare.util.ThreadUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;


/**
 * 对比失败附件下载工具
 */
public class DownCompare {
    static ThreadPoolExecutor customThreadPool;

    public static void main(String[] args) {
        startCompare();
//        listening();
    }


    static void startCompare() {
        ThreadUtils threadUtils = new ThreadUtils();
        customThreadPool = threadUtils.getCustomThreadPool();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("项目启动时间\t" + sdf.format(new Date()));

        Props props = getIniSetting();

        String tableName = props.getStr("tableName");
        String prefix = props.getStr("prefix");
        Integer start = props.getInt("start");
        Integer size = props.getInt("size");

        SqlSessionFactory sqlSessionFactory = MyBatisPlusConfig.getSqlSessionFactory(props);
        try (SqlSession session = sqlSessionFactory.openSession(true)) {
            // 获取对比失败数据并分组
            ObsCompareMapper obsCompareMapperSel = session.getMapper(ObsCompareMapper.class);
            List<ObsCompare> allList = obsCompareMapperSel.getAllList(tableName, start, size);
            System.out.println("总数据量：" + allList.size());
            List<List<ObsCompare>> partition = ListUtils.partition(allList, 1000);

            for (int index = 0; index < partition.size(); index++) {
                // 每1000条一个线程获取数据
                List<ObsCompare> obsCompares = partition.get(index);

                // 加入线程去下载附件
                customThreadPool.execute(() -> {
                    System.out.println("当前线程：" + Thread.currentThread().getName());
                    Date startDate = new Date();
                    try (SqlSession session1 = sqlSessionFactory.openSession(true)) {
                        ObsCompareMapper obsCompareMapperUpd = session1.getMapper(ObsCompareMapper.class);
                        System.out.println("开始执行" + customThreadPool.getTaskCount());
                        System.out.println(String.format("活动线程数%d,线程池数量%d,工作队列%s", customThreadPool.getActiveCount(), customThreadPool.getPoolSize(), customThreadPool.getQueue().size()));
                        Iterator<ObsCompare> obsCompareIterator = obsCompares.iterator();

                        // 需要修改附件下载状态的
                        List<String> successIds = new ArrayList<>();
                        // 开始迭代每一条附件
                        while (obsCompareIterator.hasNext()) {
                            ObsCompare obsCompare = obsCompareIterator.next();
                            // 判断附件是否存在
                            String fileUrl = obsCompare.getFile_url();
                            // url为空或者非http开头直接掠过
                            if (StrUtil.isEmpty(fileUrl) || !fileUrl.startsWith("http")) {
                                continue;
                            }
                            String[] parts = fileUrl.split("/");
                            int position = parts[0].length() + parts[1].length() + parts[2].length() + 2;  // 前两段长度+2个/

                            String bucketName = fileUrl.substring(8, fileUrl.indexOf("."));
                            String relativePath = fileUrl.substring(position);
                            File nasPath = FileUtil.file(prefix, bucketName, relativePath);

                            if (nasPath.exists()) {
                                successIds.add(obsCompare.getId());
                                continue;
                            }
                            // 验证http链接是否可用
                            int status = HttpUtil.createGet(fileUrl).execute().getStatus();
                            if (status == 200) {
                                // 下载数据到附件列表
                                try {
                                    HttpUtil.downloadFile(fileUrl, nasPath);
                                    // 下载之后再次验证
                                    if (nasPath.exists()) {
                                        successIds.add(obsCompare.getId());
                                    }
                                } catch (Exception e) {
                                    System.out.println("下载失败：" + obsCompare.getId());
                                }
                            } else {
                            }
                        }
                        obsCompareMapperUpd.updateSuccessStatus(successIds, tableName);
                        Date endDate = new Date();
                        System.out.println(String.format("结束时间%s,耗时：%d",sdf.format(endDate), (int)((endDate.getTime() - startDate.getTime())/1000)));
                    }
                });

            }

        }

    }

    private static Props getIniSetting() {
        Props props = new Props("conf/config.properties");
        return props;
    }

    private static void listening() {
        while (true) {
            System.out.println(String.format("活动线程数%d,线程池数量%d,工作队列%s", customThreadPool.getActiveCount(), customThreadPool.getPoolSize(), customThreadPool.getQueue().size()));
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }


}